<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.js"></script>
    <style>
        .a,
        .b,
        .c,
        .d {
            border: 1px dashed #333;
            padding: 20px;
            margin: 5px 0;
        }
    </style>
</head>

<body>
    <div id="app">
        <button @click="a++">a++</button>
        <button @click="b++">b++</button>
        <p>
            {{a}}---{{b}}
        </p>
        <hr>
        <comp-a :a="a" :b="b"></comp-a>
    </div>
</body>
<script>

    var CompC = {
        // inject接收一个对象 -> 自定义组件内接收数据的属性名,和默认配置
        inject: {
            A: {
                from: "a",   // 依赖于父组件的那个属性名
                default: 0  //  默认值
            },
            B: "b",
            C: {
                from: "c",
                default: 0
            },
        },
        data() {
            return {
                a: 100,
                b: 200,
            }
        },
        template: `<div class="c">
                 <div>我是组件C(自身数据): {{a}}---{{b}}</div>
                <div>父组件注入数据(传入数据): {{A}}---{{B}}---{{C}}</div>
            </div>`
    }


    var CompB = {
        // inject: ["a", "b"],
        // 等价于
        // inject: {
        //     a: "a",
        //     b: "b",
        // },

        // inject接收一个对象 -> 自定义组件内接收数据的属性名
        // 对应属性名接收父(代)组件传入的数据, 将其赋值给当前组件的另一个属性名
        // 当前组件["A"] = 父组件["a"]
        inject: {
            A: "a",
            B: "b",
        },
        data() {
            return {
                a: 10,
                b: 20,
            }
        },
        template: `<div class="b">
                <div>我是组件B(自身数据): {{a}}---{{b}}</div>
                <div>父组件注入数据(传入数据): {{A}}---{{B}}</div>
                <comp-c></comp-c>
            </div>`,
        components: {
            CompC
        }
    }

    var CompA = {
        // 注入数据    -> inject选项是一个数组 => 对应属性名接收父(代)组件传入的数据,保存在当前组件实例上    Vue实例["a"] = 父组件["a"]
        inject: ["a", "b"],
        data() {
            return {

            }
        },
        template: `<div class="a">
                <div>我是组件A: {{a}}---{{b}}</div>
                <comp-b></comp-b>
            </div>`,
        components: {
            CompB,
        }
    }


    // provide / inject
    // 这对选项需要一起使用，以允许一个祖先组件向其所有子孙后代注入一个依赖，不论组件层次有多深，并在其上下游关系成立的时间里始终生效

    // 如何使用 provide / inject


    // provide  => 注入依赖
    // provide 选项应该是一个对象或返回一个对象的函数, 包含着父(代)组件传入给自带组件的属性和方法
    // a. provide 选项可以是一个对象 => 传入定值(无法依赖Vue实例中的数据)


    // inject  => 对应键名引用数据
    // inject 选项应该是一个数组/对象


    // 根组件
    var app = new Vue({
        el: "#app",
        data: {
            a: 1,
            b: 2,
        },
        components: {
            CompA: CompA,
        },
        // provide 选项可以是一个对象 => 传入定值(无法依赖Vue实例中的数据)
        // provide: {
        //     // 键入: 父组件注入数据的属性名
        //     // 健值: 父组件注入数据的属性值(定值)
        //     a: 1,
        //     b: 2,
        // },

        // provide 选项可以是返回对象的函数 => (可以使用Vue实例中的数据/计算属性)    
        // 此函数默认在初始化阶段执行一次, 将返回的对象作为数据注入到子(代)组件 -> 传入的值还是定死的
        provide: function () {
            //  this 指向当前Vue实例
            console.log(11111);
            return {
                // 传入的定死的值
                a: this.a,  // 1
                b: this.b,  // 2
            }
        }
    })








</script>

</html>